{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 4.4 函数与方程(P255)\n",
    "\n",
    "sympy提供了sympy.ode.dsolve()函数用来求解常微分方程。\n",
    "\n",
    "dsolve()函数的用法如下：\n",
    "\n",
    "\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "1、定义变量和函数\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "在使用dsolve()函数之前，需要先定义相关的符号变量和未知函数。例如，要求解关于y(x)的微分方程，需要先定义x为符号变量，y为函数："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {},
   "outputs": [],
   "source": [
    "import sympy as sp\n",
    "x = sp.Symbol('x')\n",
    "y = sp.Function('y')(x)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "2、求解一阶常微分方程"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "例如，求解一阶常微分方程y'(x) = -y(x) ，可以按照以下方式编写代码 ："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Eq(y(x), C1*exp(-x))\n"
     ]
    }
   ],
   "source": [
    "import sympy as sp\n",
    "x = sp.Symbol('x')\n",
    "y = sp.Function('y')(x)\n",
    "# 定义微分方程\n",
    "ode = sp.Eq(y.diff(x), -y)\n",
    "# 求解微分方程\n",
    "solution = sp.dsolve(ode, y)\n",
    "print(solution)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "运行结果为：Eq(y(x), C1*exp(-x))，其中C1为任意常数。"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "3、求解二阶常微分方程"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "对于二阶常微分方程，如 y′′(X)+2y′(X)+y(X)=0，代码如下 ："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Eq(y(x), (C1 + C2*x)*exp(-x))\n"
     ]
    }
   ],
   "source": [
    "import sympy as sp\n",
    "x = sp.Symbol('x')\n",
    "y = sp.Function('y')(x)\n",
    "# 定义微分方程\n",
    "ode = sp.Eq(y.diff(x, 2) + 2*y.diff(x) + y, 0)\n",
    "# 求解微分方程\n",
    "solution = sp.dsolve(ode, y)\n",
    "print(solution)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "输出结果会给出该二阶常微分方程的通解。"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 4.4.1 常微分方程的通解(P256)\n",
    "\n",
    "例：求$$y' + xy = 0$$的通解。\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Eq(y(x), C1*exp(-x**2/2))\n"
     ]
    }
   ],
   "source": [
    "import sympy as sp\n",
    "\n",
    "# 定义变量\n",
    "x = sp.Symbol('x')\n",
    "y = sp.Function('y')(x)\n",
    "\n",
    "# 定义微分方程\n",
    "eq = sp.Eq(y.diff(x) + x*y, 0)\n",
    "\n",
    "# 求解微分方程\n",
    "solution = sp.dsolve(eq, y)\n",
    "print(solution)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 4.4.2 求微分方程的特解(P256)\n",
    "例：求方程\n",
    "y′′+2y′+3y=0\n",
    "满足初始条件\n",
    "y(0)=0,y′(0)=1\n",
    "的全部解。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "通解为: Eq(y(x), (C1*sin(sqrt(2)*x) + C2*cos(sqrt(2)*x))*exp(-x))\n",
      "满足初始条件的特解为: Eq(y(x), sqrt(2)*exp(-x)*sin(sqrt(2)*x)/2)\n"
     ]
    }
   ],
   "source": [
    "import sympy as sp\n",
    "\n",
    "# 定义变量\n",
    "x = sp.Symbol('x')\n",
    "y = sp.Function('y')(x)\n",
    "\n",
    "# 定义微分方程\n",
    "ode = sp.Eq(y.diff(x, 2) + 2*y.diff(x) + 3*y, 0)\n",
    "\n",
    "# 求解通解\n",
    "general_solution = sp.dsolve(ode, y)\n",
    "print(\"通解为:\", general_solution)\n",
    "\n",
    "# 代入初始条件求解特解\n",
    "ics = {y.subs(x, 0): 0, y.diff(x).subs(x, 0): 1}\n",
    "specific_solution = sp.dsolve(ode, y, ics=ics)\n",
    "print(\"满足初始条件的特解为:\", specific_solution)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "为了求得该方程在初始条件下\n",
    "y(0)=0,y′(0)=1\n",
    "的特解，需要额外指定两个超参数：ics，以及n。其中ics以集合的形式接收常微分方程的初始条件，n为因变量的指数。在本例中，ics={y(0): 0, y(x).diff(x).subs(x, 0): 1}, n=2。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "通解为: Eq(y(x), (C1*sin(sqrt(2)*x) + C2*cos(sqrt(2)*x))*exp(-x))\n",
      "满足初始条件的特解为: Eq(y(x), sqrt(2)*exp(-x)*sin(sqrt(2)*x)/2)\n"
     ]
    }
   ],
   "source": [
    "import sympy as sp\n",
    "\n",
    "# 定义变量\n",
    "x = sp.Symbol('x')\n",
    "y = sp.Function('y')(x)\n",
    "\n",
    "# 定义微分方程\n",
    "ode = sp.Eq(y.diff(x, 2) + 2*y.diff(x) + 3*y, 0)\n",
    "\n",
    "# 求解通解\n",
    "general_solution = sp.dsolve(ode, y)\n",
    "print(\"通解为:\", general_solution)\n",
    "\n",
    "# 定义初始条件\n",
    "ics = {y.subs(x, 0): 0, y.diff(x).subs(x, 0): 1}\n",
    "\n",
    "# 求解特解\n",
    "specific_solution = sp.dsolve(ode, y, ics=ics)\n",
    "print(\"满足初始条件的特解为:\", specific_solution)"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.11.9"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
